package com.project.erp.dao.system;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.project.erp.common.Constants;
import com.project.erp.common.dao.HibernateDao;
import com.project.erp.model.system.Privilege;

@Repository
public class PrivilegeDao extends HibernateDao<Privilege, Long>{
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 查询Privilege列表数据
	 * @return List<Privilege>
	 */
	public List<Privilege> queryPrivileges(Privilege privilege){
		if(null == privilege){
			return this.getAll();
		}
		List<Criterion> list = new ArrayList<Criterion>();
		if(StringUtils.isNotEmpty(privilege.getName())){
			Criterion name = Restrictions.ilike("name",privilege.getName(),MatchMode.ANYWHERE);
			list.add(name);
		}
		if(StringUtils.isNotEmpty(privilege.getMenuType())){
			Criterion menuType = Restrictions.eq("menuType",privilege.getMenuType());
			list.add(menuType);
		}
		return this.find(list.toArray(new Criterion[list.size()]));
	}
	
	/**
	 * @return 返回所有parent is null的菜单权限列表
	 */
	@SuppressWarnings("unchecked")
	public List<Privilege> getPrivilegeParentByRoot(){
		Criteria criteria = this.getSession().createCriteria(Privilege.class,"ap");
		//设置抓取数据的策略,如：FetchMode.JOIN
		criteria.setFetchMode("parent", FetchMode.SELECT);
		criteria.add(Restrictions.isNull("ap.parentId"));
		return criteria.list();
	}
	
	/**
	 * 根据树节点ID抓取一颗树
	 * @param acctPrivilegeId
	 * @return
	 */
	public Privilege getPrivilegeTree(Long privilegeId){
		//一次取出全部节点  
		this.getSession().createQuery("from Privilege as ap").list();
		//从一级缓存中取出根节点（根节点为1L）  
		Privilege tree = (Privilege) this.getSession().get(Privilege.class,privilegeId);
		return tree;
	}
	
	/**
	 * 根据父节点查询子节点数据
	 * @param parentId
	 * @return
	 */
	public List<Privilege> getChildrenByParentId(Long parentId){
		String hql = "from Privilege as ap where ap.parentId = ?";
		return this.find(hql, parentId);
	}
	
	/**
	 * 获取所有类型为menu的权限
	 * @return List<Privilege> 
	 */
	public List<Privilege> getAllPrivilegeMenuTree(){
		return find(Restrictions.eq("menuType", Constants.PRIVILEGE_TYPE_MENU));
	}
	
	@SuppressWarnings("unchecked")
	public List<Privilege> getAllPrilegeTree(){
		return createQuery("from Privilege as ap order by ap.id").list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Privilege> getPrivilegeByRoles(List<Long> roleIds){
		Criteria c = this.getSession().createCriteria(Privilege.class);
		c.createAlias("roles","roles");
		c.add(Restrictions.in("roles.id", roleIds));
		c.setFetchMode("roles", FetchMode.JOIN);
		//去除重复的记录
		c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		List<Privilege> privileges = c.list();
		return privileges;
	}
	
	//删除权限角色关联表数据
	public void deleteRolePrivilegeById(Long privilegeId){
		String sql = "delete from tbl_role_privilege where privilege_id=?";
		jdbcTemplate.update(sql, new Object[]{privilegeId});
	}
	
	//删除权限角色关联表数据
	public void deleteRolePrivilegeById(final List<Long> privilegeIds){
		String sql = "delete from tbl_role_privilege where privilege_id=?";
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter(){
			@Override
			public void setValues(PreparedStatement ps, int i)
					throws SQLException {
				ps.setLong(1, privilegeIds.get(i));
			}
			@Override
			public int getBatchSize() {
				return privilegeIds.size();
			}});
	}
	
	//删除权限角色关联表数据
	public void updateRolePrivilegeById(Long oldId,Long newId){
		String sql = "update tbl_role_privilege set privilege_id=? where privilege_id=?";
		jdbcTemplate.update(sql, new Object[]{newId,oldId});
	}
}
